/*
    抽象类实现
*/

#pragma once

#include <string>
#include <memory>
#include <functional>

#include "fields.hpp"

namespace JsonMuduoRPC
{

    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;

        void setMType(MType mtype) { _mtype = mtype; }
        void setId(const std::string id) { _id = id; }
        const MType getMType() { return _mtype; }
        const std::string getId() { return _id; }

        virtual bool serialize(std::string &body) = 0;
        virtual bool unSerialize(const std::string &body) = 0;
        virtual bool cheak() = 0;

    private:
        MType _mtype;
        std::string _id;
    };

    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;

        virtual size_t readableBytes() = 0;
        virtual int32_t peekInt32() = 0;
        virtual void retrieveInt32() = 0;
        virtual int32_t readInt32() = 0;
        virtual std::string retrieveAsString(size_t len) = 0;
    };

    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;

        virtual bool canProcessed(const BaseBuffer::ptr &) = 0;
        virtual std::string serialize(const BaseMessage::ptr &) = 0;
        virtual bool onMessage(const BaseBuffer::ptr &, BaseMessage::ptr &) = 0;
    };

    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;

        virtual bool send(const BaseMessage::ptr &) = 0;
        virtual void shutdown() = 0;
        virtual bool connected() = 0;
    };

    using connectionCallBack = std::function<void(const BaseConnection::ptr &)>;
    using closeCallBack = std::function<void(const BaseConnection::ptr &)>;
    using messageCallBack = std::function<void(const BaseConnection::ptr &, const BaseMessage::ptr &)>;

    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;

        void setConnectionCallBack(const connectionCallBack &cb) { _cb_connection = cb; }
        void setCloseCallBack(const closeCallBack &cb) { _cb_close = cb; }
        void setMessageCallBack(const messageCallBack &cb) { _cb_message = cb; }

        virtual void start() = 0;

    protected:
        connectionCallBack _cb_connection;
        closeCallBack _cb_close;
        messageCallBack _cb_message;
    };

    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;

        void setConnectionCallBack(const connectionCallBack &cb) { _cb_connection = cb; }
        void setCloseCallBack(const closeCallBack &cb) { _cb_close = cb; }
        void setMessageCallBack(const messageCallBack &cb) { _cb_message = cb; }

        virtual void connect() = 0;
        virtual bool connected() = 0;
        virtual BaseConnection::ptr connection() = 0;
        virtual bool send(const BaseMessage::ptr &) = 0;
        virtual void shutdown() = 0;

    protected:
        connectionCallBack _cb_connection;
        closeCallBack _cb_close;
        messageCallBack _cb_message;
    };
} // namespace JsonMuduoRPC
